package com.glsc.ngateway.platform.service.easyflow;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.glsc.ngateway.common.api.flowable.dto.FlowDoTaskRespDto;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.easyflow.BaseFlowForm;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.platform.service.FlowCommonService;
import com.glsc.ngateway.platform.service.easyflow.dto.FlowDataDto;
import com.glsc.ngateway.platform.service.easyflow.dto.ParamDoTaskRespDto;
import com.glsc.ngateway.platform.service.easyflow.dto.WorkflowMsgDto;
import com.glsc.ngateway.platform.service.itflow.aspect.ItFlowAuthentication;
import com.glsc.ngateway.platform.service.itflow.config.ProcessEditConfigService;
import com.glsc.ngateway.platform.utils.SpringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
 * @author zzp
 * @date 2024/03/06
 * 通用flowable流程服务类
 */
@Service
public class EasyFlowService {

    Logger logger = LoggerFactory.getLogger(EasyFlowService.class);

    @Resource
    private FlowCommonService flowableService;

    @Resource
    private ProcessEditConfigService processEditConfigService;


    @Resource
    private EasyFlowStrategyAdapter easyFlowStrategyAdapter;

    /**
     * 创建流程
     *
     * @param flowDataDto     流程创建发起对象
     * @param operatorAccount 发起人OA账号
     * @return
     */
    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto createFlow(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return easyFlowStrategyAdapter.createFlow(flowDataDto, operatorAccount);
    }

    /**
     * 保存节点数据，但是不提交任务，（不包括还未创建流程时，保存草稿的场景）
     */
    @ItFlowAuthentication
    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto saveOrUpdateForm(FlowDataDto<TYPEFORM> flowDataDto, @NotBlank String operatorAccount) {
        if (ObjectUtil.isNull(flowDataDto)
                || ObjectUtil.isNull(flowDataDto.getFormMainData())
                || StrUtil.isEmpty(operatorAccount)) {
            throw PlatformException.error("流程保存必填要素不能为空");
        }

        //【1.任务合法性数据】
        FlowDoTaskRespDto checkRespDto = flowableService.validCheckTaskBeforeSaveFormOrAuditTask(flowDataDto.getTaskId());
        SpringUtil.copyPropertiesIgnoreNull(checkRespDto, flowDataDto);

        ParamDoTaskRespDto respDto = easyFlowStrategyAdapter.saveOrUpdateForm(flowDataDto, operatorAccount);
        return respDto;
    }

    /**
     * 审核通过
     */
    @ItFlowAuthentication
    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto taskAuditPass(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return easyFlowStrategyAdapter.taskAuditPass(flowDataDto, operatorAccount);
    }


    /**
     * 审核驳回
     */
    @ItFlowAuthentication
    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto taskAuditReject(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return easyFlowStrategyAdapter.reject(flowDataDto, operatorAccount);
    }

    /**
     * 强制终止
     */
    @ItFlowAuthentication
    public <TYPEFORM extends BaseFlowForm> void processStop(@NotNull FlowDataDto<TYPEFORM> flowDataDto, String operatorAccount) {
        easyFlowStrategyAdapter.processStop(flowDataDto, operatorAccount);
    }

    /**
     * 根据流程实例ID或者任务ID检索流程
     */
    @ItFlowAuthentication
    public <TYPEFORM extends BaseFlowForm> FlowDataDto<TYPEFORM> findByProcessIdOrTaskId(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return easyFlowStrategyAdapter.findByProcessIdOrTaskId(flowDataDto, operatorAccount);
    }


    /**
     * 处理消息
     */
    public void processMsg(WorkflowMsgDto msgDto) {
        easyFlowStrategyAdapter.processMsg(msgDto);
    }
}
